package com.tanger.common.utils;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description mybatis-plus代码生成器
 * @Author Hchenbin
 * @Date 2022-08-24 18:43
 * @Version 1.0
 */
@Component
public class CodeGenerator {

    @Value("${spring.datasource.url}")
    private String datasource_url;
    @Value("${spring.datasource.username}")
    private String datasource_name;
    @Value("${spring.datasource.password}")
    private String datasource_password;
    @Value("${spring.datasource.driver-class-name}")
    private String datasource_driver;

    public static String datasourceUrl;
    public static String datasourceName;
    public static String datasourcePassword;
    public static String datasourceDriver;

    /**
     * 生成文件根目录及包名
     */
    private static final String PACKAGE_CONTROLLER_NAME = "controller";
    private static final String PACKAGE_SERVICE_NAME = "service";
    private static final String PACKAGE_SERVICEIMPL_NAME = "service.impl";
    private static final String PACKAGE_ENTITY_NAME = "entity";
    private static final String PACKAGE_MAPPER_NAME = "repository";
    private static final String MAPPER_XML_PATH = "repository";

    @PostConstruct
    public void init() {
        datasourceUrl = datasource_url;
        datasourceName = datasource_name;
        datasourcePassword = datasource_password;
        datasourceDriver = datasource_driver;
    }

    /**
     * 数据源配置
     *
     * @return
     */
    private static DataSourceConfig getDataSourceConfig() {
        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl(datasourceUrl);
        dsc.setDbType(DbType.MYSQL);
        dsc.setDriverName(datasourceDriver);
        dsc.setUsername(datasourceName);
        dsc.setPassword(datasourcePassword);
        return dsc;
    }

    /**
     * @description 全局配置
     * @param rootDir 根目录=项目名称/src/main/java
     * @param author 作者
     * @return
     */
    private static GlobalConfig getGlobalConfig(String rootDir,String author) {
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir(rootDir);
        gc.setFileOverride(true);
        gc.setActiveRecord(true);
        // XML 二级缓存
        gc.setEnableCache(false);
        // XML ResultMap
        gc.setBaseResultMap(true);
        // XML columList
        gc.setBaseColumnList(true);
        gc.setAuthor(author);
        gc.setMapperName("%sMapper");
        gc.setXmlName("%sMapper");
        gc.setServiceName("%sService");
        gc.setServiceImplName("%sServiceImpl");
        gc.setControllerName("%sController");
        return gc;
    }

    /**
     * @description 生成策略配置
     * @param tablePrefixs 数据库表名前缀
     * @param tables 数据库表名数组
     * @return
     */
    private static StrategyConfig getStrategyConfig(String tablePrefixs,String[] tables) {
        StrategyConfig strategy = new StrategyConfig();
        // 此处为表前缀
        strategy.setTablePrefix(tablePrefixs);
        // 表名生成策略
        strategy.setNaming(NamingStrategy.underline_to_camel);
        // 需要生成的表
        strategy.setInclude(tables);
        strategy.setEntityLombokModel(true);
        return strategy;
    }

    /**
     * @description 生成包名设置
     * @param parentName 父级包结构如:com.brt.base.user
     * @return
     */
    private static PackageConfig getPackageConfig(String parentName) {
        // 4.生成文件所在包配置：
        PackageConfig pc = new PackageConfig();
        pc.setParent(parentName);
        pc.setController(PACKAGE_CONTROLLER_NAME);
        pc.setService(PACKAGE_SERVICE_NAME);
        pc.setServiceImpl(PACKAGE_SERVICEIMPL_NAME);
        pc.setEntity(PACKAGE_ENTITY_NAME);
        pc.setMapper(PACKAGE_MAPPER_NAME);
        return pc;
    }

    /**
     * @description xml文件配置
     * @return
     */
    private static InjectionConfig getInjectionConfig(String rootDir,String parentName) {
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> map = new HashMap<>();
                //map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-rb");
                this.setMap(map);
            }
        };
        //xml生成路径
        List<FileOutConfig> focList = new ArrayList<>();
        focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return rootDir + "/" + parentName + "/" + MAPPER_XML_PATH + "/" + tableInfo.getEntityName() + "Mapper.xml";
            }
        });
        cfg.setFileOutConfigList(focList);
        return cfg;
    }

    /**
     * @description 关闭默认 xml 生成
     * @return
     */
    private static TemplateConfig getTemplateConfig() {
        TemplateConfig tc = new TemplateConfig();
        tc.setXml(null);
        return tc;
    }

    /**
     * @description 代码生成器
     * @param rootDir 根目录:brt-base-service-user/src/main/java
     * @param author 作者
     * @param tablePrefixs 表前缀
     * @param tables 表数组
     * @param parentName 父级包目录:com.brt.base.user
     */
    public static void generator( String rootDir,String author,String tablePrefixs,String[] tables,String parentName){
        AutoGenerator mpg = new AutoGenerator();
        mpg.setDataSource(getDataSourceConfig());
        mpg.setGlobalConfig(getGlobalConfig(rootDir,author));
        mpg.setStrategy(getStrategyConfig(tablePrefixs,tables));
        mpg.setPackageInfo(getPackageConfig(parentName));
        mpg.setCfg(getInjectionConfig(rootDir,parentName));
        mpg.setTemplate(getTemplateConfig());
        // 执行生成
        mpg.execute();
    }

    public static void main(String[] args) {
        //根目录
        String rootDir = "brt-base-business/src/main/java";
        //作者
        String author = "Hchenbin";
        //表前缀
        String tablePrefixs = "t_";
        //表数组
        String[] tables = new String[]{"t_base_config","t_base_theme"};
        //父级包目录
        String parentName = "com.brt.base.business";
        AutoGenerator mpg = new AutoGenerator();
        mpg.setDataSource(getDataSourceConfig());
        mpg.setGlobalConfig(getGlobalConfig(rootDir,author));
        mpg.setStrategy(getStrategyConfig(tablePrefixs,tables));
        mpg.setPackageInfo(getPackageConfig(parentName));
        mpg.setCfg(getInjectionConfig(rootDir,parentName));
        mpg.setTemplate(getTemplateConfig());
        // 执行生成
        mpg.execute();
    }
}
